﻿using Springwater.Business.Excel;
using Springwater.Business.Util;
using Springwater.DataAccessLayer.Repository;
using Springwater.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Springwater.Business.Import
{
    public class BorvizImport
    {
        private UnitOfWork unitOfWork = null;

        public BorvizImport(UnitOfWork unitOfWork)
        {
            this.unitOfWork = unitOfWork;
        }

        public List<string> Process(List<Dictionary<string, string>> listDictionary, ref ImportStatistic importStatistic)
        {
            List<Borviz> borvizList = new List<Borviz>();

            foreach (var dictionary in listDictionary)
            {
                var borviz = ProcessItem(dictionary, ref importStatistic);

                if (borvizList.Any(b => b.Kod.Equals(borviz.Kod, StringComparison.OrdinalIgnoreCase)))
                {
                    if (borviz.Id == 0) importStatistic.NewBorviz--;
                    else importStatistic.UpdatedBorviz--;

                    var existingBorviz = borvizList.First(b => b.Kod.Equals(borviz.Kod, StringComparison.OrdinalIgnoreCase));
                    existingBorviz.Meresek.Add(borviz.Meresek.FirstOrDefault());
                }
                else
                {
                    borvizList.Add(borviz);

                    if (borviz.Id == 0)
                    {
                        this.unitOfWork.BorvizRepository.Insert(borviz);
                    }
                }
            }

            if (importStatistic.ErrorList.Count == 0)
            {
                return this.unitOfWork.SafeSave();
            }
            else
            {
                return importStatistic.ErrorList;
            }
        }

        private Borviz ProcessItem(Dictionary<string, string> dictionary, ref ImportStatistic importStatistic)
        {
            Borviz borviz = this.unitOfWork.BorvizRepository.GetByKod(dictionary[ExcelTemplate.Column.Kod]);

            if (borviz == null)
            {
                importStatistic.NewBorviz++;
                borviz = new Borviz();
            }
            else
            {
                importStatistic.UpdatedBorviz++;
            }

            borviz.Kod = dictionary[ExcelTemplate.Column.Kod];

            if (!string.IsNullOrEmpty(dictionary[ExcelTemplate.Column.Tájegység])) borviz.Tajegyseg = dictionary[ExcelTemplate.Column.Tájegység];
            if (!string.IsNullOrEmpty(dictionary[ExcelTemplate.Column.Eredet])) borviz.Eredet = dictionary[ExcelTemplate.Column.Eredet];

            #region Elnevezes

            if (!string.IsNullOrEmpty(dictionary[ExcelTemplate.Column.ElőfordulasNeve]))
            {
                string[] nevek = dictionary[ExcelTemplate.Column.ElőfordulasNeve].Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                bool elsodleges = true;

                foreach (string nev in nevek)
                {
                    if (!borviz.Elnevezes.Any(elnevezes => elnevezes.Nev.Equals(nev.Trim(), StringComparison.InvariantCultureIgnoreCase)))
                    {
                        borviz.Elnevezes.Add(new Elnevezes() { Nev = nev.Trim(), Elsodleges = elsodleges });
                    }

                    elsodleges = false;
                }
            }

            #endregion

            #region FoldfelsziniHelyzet

            if (borviz.FoldfelsziniHelyzet == null)
            {
                borviz.FoldfelsziniHelyzet = new FoldfelsziniHelyzet();
            }

            if (!string.IsNullOrEmpty(dictionary[ExcelTemplate.Column.GPSEst]) && !string.IsNullOrEmpty(dictionary[ExcelTemplate.Column.GPSNord]))
            {
                borviz.FoldfelsziniHelyzet.Latitude = GpsUtil.StringToDD(dictionary[ExcelTemplate.Column.GPSNord]);
                borviz.FoldfelsziniHelyzet.Longitude = GpsUtil.StringToDD(dictionary[ExcelTemplate.Column.GPSEst]);
            }

            if (!string.IsNullOrEmpty(dictionary[ExcelTemplate.Column.Magasság]))
            {
                borviz.FoldfelsziniHelyzet.Magassag = short.Parse(dictionary[ExcelTemplate.Column.Magasság].Replace("m", string.Empty));
            }

            #endregion

            #region Vizgyujto

            if (!string.IsNullOrEmpty(dictionary[ExcelTemplate.Column.Vízgyűjtő]))
            {
                string[] nevek = dictionary[ExcelTemplate.Column.Vízgyűjtő].Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);

                foreach (string nev in nevek)
                {
                    if (!borviz.Vizgyujtok.Any(v => v.Nev.Equals(nev.Trim(), StringComparison.InvariantCultureIgnoreCase)))
                    {
                        var vizgyujto = unitOfWork.VizgyujtoRepository.Get(v => v.Nev.Equals(nev.Trim(), StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();

                        if (vizgyujto != null)
                        {
                            borviz.Vizgyujtok.Add(vizgyujto);
                        }
                        else
                        {
                            importStatistic.ErrorList.Add(string.Format("Kod: {0} - Ervenytelen vizgyujto: {1}", borviz.Kod, nev));
                        }
                    }
                }
            }

            #endregion

            #region Meres

            if (!string.IsNullOrEmpty(dictionary[ExcelTemplate.Column.Dátum]))
            {
                DateTime datum = DateTime.Now;

                if (DateTime.TryParse(dictionary[ExcelTemplate.Column.Dátum], out datum))
                {
                    var meres = this.unitOfWork.MeresRepository.FirstOrDefault(m => m.BorvizId == borviz.Id && m.Datum.Year == datum.Year && m.Datum.Month == datum.Month && m.Datum.Day == datum.Day);

                    if (meres == null)
                    {
                        importStatistic.NewMeasurement++;
                        meres = new Meres() {};

                        borviz.Meresek.Add(meres);
                    }
                    else
                    {
                        importStatistic.UpdatedMeasurement++;
                    }

                    meres.Datum = datum;
                    meres.Gazfeltores = GetBool(dictionary, ExcelTemplate.Column.Gázfeltörés, importStatistic.ErrorList);
                    meres.Homerseklet = GetDouble(dictionary, ExcelTemplate.Column.Hőmérséklet, importStatistic.ErrorList);
                    meres.Kond = GetDouble(dictionary, ExcelTemplate.Column.Kond, importStatistic.ErrorList);
                    meres.TDS = GetInt(dictionary, ExcelTemplate.Column.TDS, importStatistic.ErrorList);

                    meres.PH = GetDouble(dictionary, ExcelTemplate.Column.pH, importStatistic.ErrorList);
                    meres.Sotartalom = GetDouble(dictionary, ExcelTemplate.Column.Sótartalom, importStatistic.ErrorList);
                    meres.CO2 = (short?)GetInt(dictionary, ExcelTemplate.Column.CO2, importStatistic.ErrorList);
                    meres.HCO3 = GetDouble(dictionary, ExcelTemplate.Column.HCO3, importStatistic.ErrorList);
                    meres.Ca = (short?)GetInt(dictionary, ExcelTemplate.Column.Ca, importStatistic.ErrorList);

                    meres.Mg = (short?)GetInt(dictionary, ExcelTemplate.Column.Mg, importStatistic.ErrorList);
                    meres.NH4 = GetDouble(dictionary, ExcelTemplate.Column.NH4, importStatistic.ErrorList);
                    meres.NO3 = GetDouble(dictionary, ExcelTemplate.Column.NO3, importStatistic.ErrorList);
                    meres.Fe = GetDouble(dictionary, ExcelTemplate.Column.Fe, importStatistic.ErrorList);
                    meres.Cl = (short?)GetInt(dictionary, ExcelTemplate.Column.Cl, importStatistic.ErrorList);
                    meres.PO4 = (short?)GetInt(dictionary, ExcelTemplate.Column.PO4, importStatistic.ErrorList);

                    meres.Szerzo = "System";
                    meres.Vizhozam = GetVizhozam(dictionary, meres.Vizhozam, importStatistic.ErrorList);

                    #region Megfigyeles

                    if (meres.Megfigyeles == null) meres.Megfigyeles = new Megfigyeles();
                    meres.Megfigyeles.Allapot = dictionary[ExcelTemplate.Column.Állapot];
                    meres.Megfigyeles.Forma = dictionary[ExcelTemplate.Column.Forma];
                    meres.Megfigyeles.Kiepitettseg = dictionary[ExcelTemplate.Column.Kiépítettség];
                    meres.Megfigyeles.KornyezetiVeszely = dictionary[ExcelTemplate.Column.KörnyezetiVeszélyeztetettség];

                    #endregion
                }
                else
                {
                    importStatistic.ErrorList.Add(string.Format("Kod: {0} - Ervenytelen datum: {1}", borviz.Kod, dictionary[ExcelTemplate.Column.Dátum]));
                }
            }


            #endregion

            return borviz;
        }

        private bool? GetBool(Dictionary<string, string> dictionary, string key, List<string> errorList)
        {
            if (string.IsNullOrWhiteSpace(dictionary[key])) return null;

            bool? value = null;

            if (key == ExcelTemplate.Column.Gázfeltörés)
            {
                switch (dictionary[ExcelTemplate.Column.Gázfeltörés].ToLower())
                {
                    case "igen":
                        value = true; break;
                    case "nem":
                    case "nincs":
                        value = false; break;
                    case "nem eszlelheto":
                        value = null;
                        break;
                    default:
                        errorList.Add(string.Format("Kod: {0} - Ervenytelen Gázfeltörés: {1}", dictionary[ExcelTemplate.Column.Kod], dictionary[key]));
                        break;
                }
            }

            return value;
        }

        private double? GetDouble(Dictionary<string, string> dictionary, string key, List<string> errorList)
        {
            if (string.IsNullOrWhiteSpace(dictionary[key])) return null;

            double value = 0;

            if (!double.TryParse(dictionary[key], out value))
            {
                errorList.Add(string.Format("Kod: {0} - Ervenytelen {1}: {2}", dictionary[ExcelTemplate.Column.Kod], key, dictionary[key]));
                return null;
            }

            return value;
        }

        private int? GetInt(Dictionary<string, string> dictionary, string key, List<string> errorList)
        {
            if (string.IsNullOrWhiteSpace(dictionary[key])) return null;

            int value = 0;

            if (!int.TryParse(dictionary[key], out value))
            {
                errorList.Add(string.Format("Kod: {0} - Ervenytelen {1}: {2}", dictionary[ExcelTemplate.Column.Kod], key, dictionary[key]));
                return null;
            }

            return value;
        }

        private Vizhozam GetVizhozam(Dictionary<string, string> dictionary, Vizhozam vizhozam, List<string> errorList)
        {
            string str = dictionary[ExcelTemplate.Column.Vízhozam];
            if (string.IsNullOrWhiteSpace(str))
            {
                if (vizhozam != null) this.unitOfWork.VizhozamRepository.Delete(vizhozam);
                return null;
            }

            switch (str)
            {
                case "elhanyagolható":
                case "elhanyagolhato":
                    if (vizhozam == null) vizhozam = new Vizhozam();
                    vizhozam.Elhanyagolhato = true;
                    vizhozam.NemMerheto = null;
                    vizhozam.Hozam = null;
                    vizhozam.NemMerhetoNagyHozam = null;
                    break;
                case "nem merheto":
                case "mérhetetlen":
                case "nem mérhető":
                    if (vizhozam == null) vizhozam = new Vizhozam();
                    vizhozam.NemMerheto = true;
                    vizhozam.Elhanyagolhato = null;
                    vizhozam.Hozam = null;
                    vizhozam.NemMerhetoNagyHozam = null;
                    break;
                case "nem merheto, nagy hozam":
                    if (vizhozam == null) vizhozam = new Vizhozam();
                    vizhozam.NemMerheto = null;
                    vizhozam.Elhanyagolhato = null;
                    vizhozam.Hozam = null;
                    vizhozam.NemMerhetoNagyHozam = true;
                    break;
                default:
                    double hozam = 0;

                    if (double.TryParse(str, out hozam))
                    {
                        if (vizhozam == null) vizhozam = new Vizhozam();
                        vizhozam.NemMerheto = null;
                        vizhozam.Elhanyagolhato = null;
                        vizhozam.Hozam = hozam;
                        vizhozam.NemMerhetoNagyHozam = null;
                    }
                    else
                    {
                        vizhozam = null;
                        errorList.Add(string.Format("Kod: {0} - Ervenytelen Vizhozam: {1}", dictionary[ExcelTemplate.Column.Kod], str));
                    }
                    break;
            }

            return vizhozam;
        }
    }
}
